package com.frinder.akka;

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.PoisonPill;
import akka.pattern.Patterns;
import akka.util.Timeout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import scala.concurrent.Await;
import scala.concurrent.Future;
import scala.concurrent.duration.FiniteDuration;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * Created by frinder on 2017/7/26.
 */
@Component
public class AkkaRunner implements CommandLineRunner {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private ActorSystem actorSystem;

    @Autowired
    private SpringExtension springExtension;

    @Override
    public void run(String... strings) throws Exception {
        ActorRef masterActor = actorSystem.actorOf(springExtension.props("masterActor").withMailbox("akka.priority-mailbox"), "master-actor");
//        ActorRef workerActor = actorSystem.actorOf(springExtension.props("workerActor"), "worker-actor");
//        workerActor.tell(new AkkaRequest("hello world.", 1), masterActor);
//        workerActor.tell(new AkkaRequest("hi, master.", 1), masterActor);
//        workerActor.tell(new AkkaRequest("hahaha.", 1), masterActor);

//        for (int i = 0; i < 10; i++) {
//            masterActor.tell(new AkkaRequest("hello world.." + i, new Random().nextInt(99)), masterActor);
//        }

//        masterActor.tell(PoisonPill.getInstance(), null);

        FiniteDuration duration = FiniteDuration.create(100, TimeUnit.SECONDS);
        Future<Object> future = Patterns.ask(masterActor, new AkkaRequest("future", 1), Timeout.durationToTimeout(duration));
        logger.info("Response : {}", Await.result(future, duration));


//        while (!masterActor.isTerminated()) {
//            Thread.sleep(100);
//        }
//        actorSystem.terminate();
//        actorSystem.awaitTermination();
    }
}
